<template>
  <div v-if="props.showValue" class="c-select-wrapper">
    <el-popover
      placement="top-start"
      title="上手值"
      effect="dark"
      :width="200"
      trigger="hover"
      :disabled="!showOldValue"
      :content="oldValue ? oldValue : '无'"
    >
      <template #reference>
        <el-select
          v-model="selectedValue"
          :placeholder="placeholder"
          :disabled="disabled || isLoading"
          :filterable="filterable"
          :remote="remote"
          :remote-method="handleRemoteMethod"
          :loading="isLoading"
          :class="{
            'show-red': props.oldValue != selectedValue && showOldValue,
            'invalid-value': isInvalidSelected,
          }"
          v-bind="$attrs"
          @change="handleChange"
          @clear="handleClear"
          @visible-change="handleVisibleChange"
        >
          <template v-if="emptyText" #empty>
            <div class="empty-text">{{ emptyText }}</div>
          </template>
          <template v-if="noDataText" #no-data>
            <div class="no-data-text">{{ noDataText }}</div>
          </template>
          <el-option
            v-for="item in optionsData"
            :key="item[valueKey]"
            :label="item[labelKey]"
            :value="item[valueKey]"
            :disabled="item[disabledKey]"
          >
            <template v-if="optionRender" #default="data">
              <slot name="optionRender" :option="item" :data="data"></slot>
            </template>
          </el-option>
        </el-select>
      </template>
    </el-popover>
    <div v-if="showRequiredMark && !hideRequiredMark" class="required-mark">*</div>
  </div>
</template>
<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { ElSelect } from 'element-plus'

/**
 * Select 二次封装，增强了以下功能：
 * 1. 远程搜索时的加载状态管理
 * 2. 自定义空数据和无匹配项的提示文本
 * 3. 可配置的required标记
 * 4. 统一的选项数据处理
 * 5. 选项的自定义渲染支持
 * 6. 显示上手值
 * 7. 是否变红逻辑
 */
const props = defineProps({
  // 绑定值
  modelValue: {
    type: [String, Number, Boolean, Object, Array],
    default: '',
  },
  // 选项数据
  options: {
    type: Array<any>,
    default: () => [],
  },
  // 占位符
  placeholder: {
    type: String,
    default: '',
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 是否可筛选
  filterable: {
    type: Boolean,
    default: false,
  },
  // 是否为远程搜索
  remote: {
    type: Boolean,
    default: false,
  },
  // 远程搜索方法
  remoteMethod: {
    type: Function,
    default: () => {},
  },
  // 是否显示加载状态
  loading: {
    type: Boolean,
    default: false,
  },
  // 空数据时的提示文本
  emptyText: {
    type: String,
    default: '',
  },
  // 无匹配项时的提示文本
  noDataText: {
    type: String,
    default: '',
  },
  // 选项的value字段名
  valueKey: {
    type: String,
    default: 'value',
  },
  // 选项的label字段名
  labelKey: {
    type: String,
    default: 'label',
  },
  // 选项的disabled字段名
  disabledKey: {
    type: String,
    default: 'disabled',
  },
  // 是否显示必填标记
  showRequiredMark: {
    type: Boolean,
    default: false,
  },
  // 是否隐藏必填标记（优先级高于showRequiredMark）
  hideRequiredMark: {
    type: Boolean,
    default: false,
  },
  // 是否支持自定义选项渲染
  optionRender: {
    type: Boolean,
    default: false,
  },
  // 是否显示
  showValue: {
    type: Boolean,
    default: true,
  },
  // 是否显示上手值
  showOldValue: {
    type: Boolean,
    default: false,
  },
  // 上手值
  oldValue: {
    type: String,
    default: '',
  },
})

const emit = defineEmits([
  'update:modelValue',
  'change',
  'clear',
  'visible-change',
  'focus',
  'blur',
])

// 内部选中值
const selectedValue = ref(props.modelValue)
// 内部加载状态
const isLoading = ref(props.loading)
// 处理后的选项数据 - 过滤掉isvalid不是'1'的选项
const optionsData = computed(() => {
  return props.options.filter((item) => {
    // 如果没有isvalid字段，默认认为有效
    return item.isvalid === undefined || item.isvalid === '1'
  })
})

// 获取选中项的信息（包括无效选项）
const selectedOption = computed(() => {
  if (!selectedValue.value) return null
  // 先从所有选项中查找（包括无效选项）
  return props.options.find((item) => item[props.valueKey] === selectedValue.value)
})

// 判断当前选中的值是否为无效值
const isInvalidSelected = computed(() => {
  if (!selectedOption.value) return false
  // 只有当存在isvalid字段且不为'1'时才认为是无效值
  return selectedOption.value.isvalid !== undefined && selectedOption.value.isvalid !== '1'
})

// 监听modelValue变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedValue.value = newVal
  },
)

// 监听外部loading状态变化
watch(
  () => props.loading,
  (newVal) => {
    isLoading.value = newVal
  },
)

// 处理值变化
const handleChange = (value: any) => {
  selectedValue.value = value
  emit('update:modelValue', value)
  emit('change', value)
}

// 处理清除
const handleClear = () => {
  selectedValue.value = ''
  emit('update:modelValue', '')
  emit('clear')
}

// 处理下拉框显示状态变化
const handleVisibleChange = (visible: boolean) => {
  emit('visible-change', visible)
}

// 处理远程搜索
const handleRemoteMethod = async (query: string) => {
  if (props.remoteMethod) {
    try {
      isLoading.value = true
      await props.remoteMethod(query)
    } finally {
      isLoading.value = false
    }
  }
}
</script>

<style lang="scss" scoped>
.c-select-wrapper {
  position: relative;
  display: inline-block;
  width: 100%;
}

.required-mark {
  position: absolute;
  right: -12px;
  top: 50%;
  transform: translateY(-50%);
  color: #f56c6c;
  font-size: 14px;
}

.empty-text,
.no-data-text {
  text-align: center;
  color: #909399;
  padding: 10px 0;
}

:deep(.show-red) .el-select__selected-item {
  color: red;
}

:deep(.invalid-value) .el-select__selected-item {
  color: #909399;
}
</style>
